package cn.redragon.soa.config.redis;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.CacheResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;

/**
 * @Author: Steven HUANG
 * @Date: 2021/1/15
 */
@Slf4j
@EnableCaching
@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
@EnableConfigurationProperties({CacheProperties.class})
@ConditionalOnClass({CacheProperties.Redis.class, RedisCacheConfiguration.class})
@ConditionalOnProperty(value = "spring.cache.enabled", havingValue = "true")
public class RedisCacheConfig {

    @Qualifier("commonObjectMapper")
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private CacheProperties cacheProperties;
    @Autowired
    private RedisGenericCacheProcessor redisGenericCacheProcessor;

    @Bean
    public RedisCacheManager redisCacheManager(LettuceConnectionFactory lettuceConnectionFactory) {
        RedisCacheConfiguration defaultConfiguration = RedisCacheHelper.redisCacheConfiguration(cacheProperties,
                                                                                                new GenericJackson2JsonRedisSerializer(objectMapper));

        RedisGenericCacheManager cacheManager = new RedisGenericCacheManager(RedisCacheWriter.nonLockingRedisCacheWriter(lettuceConnectionFactory),
                                                                             defaultConfiguration);
        cacheManager.initGenericCacheMap(redisGenericCacheProcessor.getGenericCacheMap());
        cacheManager.setCacheProperties(cacheProperties);
        cacheManager.setObjectMapper(objectMapper);
        return cacheManager;
    }

    @Bean("emptyCacheResolver")
    public CacheResolver emptyCacheResolver(RedisCacheManager redisCacheManager) {
        return new EmptyCacheResolver(redisCacheManager);
    }
}
